package vip.zhenzicheng.concurrent_program.thread.sgg.locksupport;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhenzicheng
 * @date 2022-06-28 09:41
 */
public class LockSupportDemo {

  public static void main(String[] args) {
    // syncWaitNotify();
    // lockAwaitSignal();
    // lockSupportParkUnpark();
  }

  // public static void main(String[] args) {
  //   int[] ints1 = {1, 3, 5, 7, 9};
  //   int[] ints2 = {2, 3, 4, 6};
  //   int[] ints3 = new int[ints1.length + ints2.length];
  //   System.arraycopy(ints1, 0, ints3, 0, ints1.length);
  //   System.arraycopy(ints2, 0, ints3, ints1.length, ints2.length);
  //   System.out.println(Arrays.toString(ints3));
  // }

  private static void lockSupportParkUnpark() {
    Thread t1 = new Thread(() -> {
      try {
        TimeUnit.SECONDS.sleep(3); // 先阻塞，让t2先unpark
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + "\t" + System.currentTimeMillis());
      LockSupport.park();
    }, "t1");
    t1.start();

    new Thread(() -> {
      LockSupport.unpark(t1);
      System.out.println(Thread.currentThread().getName() + "\t" + System.currentTimeMillis() + "----unpark over");
    }, "t2").start();
  }

  /*使用Lock与Condition*/
  private static void lockAwaitSignal() {
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    new Thread(() -> {
      lock.lock();
      try {
        System.out.println(Thread.currentThread().getName() + "\t ----come in");
        condition.await();
        System.out.println(Thread.currentThread().getName() + "\t ----被唤醒");
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally {
        lock.unlock();
      }
    }, "t1").start();

    try {
      TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    new Thread(() -> {
      lock.lock();
      try {
        condition.signal();
        System.out.println(Thread.currentThread().getName() + "\t ----发出通知");
      } finally {
        lock.unlock();
      }
    }, "t2").start();
  }

  /*使用同步代码块原生方式*/
  private static void syncWaitNotify() {
    Object o = new Object();

    new Thread(() -> {
      synchronized (o) {
        System.out.println(Thread.currentThread().getName() + "\t ----come in");
        try {
          o.wait();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "\t ----被唤醒");
      }
    }, "t1").start();

    try {
      TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    new Thread(() -> {
      synchronized (o) {
        o.notify();
        System.out.println(Thread.currentThread().getName() + "\t ----发出通知");
      }
    }, "t2").start();
  }
}
